#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
主窗口界面模块
"""

import os
import sys
import json
from PyQt5.QtWidgets import (QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, 
                            QPushButton, QFileDialog, QLabel, QLineEdit, 
                            QProgressBar, QListWidget, QSlider, QGroupBox,
                            QFormLayout, QSpinBox, QDoubleSpinBox, QMessageBox,
                            QStyleFactory, QComboBox, QCheckBox, QApplication)
from PyQt5.QtCore import Qt, QThread, pyqtSignal
from PyQt5.QtGui import QDragEnterEvent, QDropEvent, QIcon, QFont, QPalette, QColor
from core.processor import VideoProcessor

# 配置文件路径
CONFIG_FILE = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'config.json')

# 界面样式表
STYLE_SHEET = """
QMainWindow {
    background-color: #f5f5f7;
}

QGroupBox {
    font-weight: bold;
    border: 1px solid #cccccc;
    border-radius: 5px;
    margin-top: 1ex;
    padding-top: 10px;
}

QGroupBox::title {
    subcontrol-origin: margin;
    left: 10px;
    padding: 0 3px;
}

QPushButton {
    background-color: #007aff;
    color: white;
    border-radius: 4px;
    padding: 5px 15px;
    font-weight: bold;
}

QPushButton:hover {
    background-color: #1a87ff;
}

QPushButton:pressed {
    background-color: #0062cc;
}

QPushButton:disabled {
    background-color: #cccccc;
    color: #666666;
}

QProgressBar {
    border: 1px solid #cccccc;
    border-radius: 4px;
    text-align: center;
    height: 25px;
}

QProgressBar::chunk {
    background-color: #007aff;
    width: 10px;
    margin: 0.5px;
}

QListWidget {
    border: 1px solid #cccccc;
    border-radius: 4px;
    background-color: white;
}

QLineEdit {
    border: 1px solid #cccccc;
    border-radius: 4px;
    padding: 5px;
    background-color: white;
}

QLabel {
    color: #333333;
}

#dragHint {
    color: #666666;
    font-style: italic;
    padding: 10px;
}

#statusLabel {
    font-weight: bold;
    font-size: 14px;
    color: #333333;
}
"""


class ProcessingThread(QThread):
    """
    处理视频的工作线程，避免界面卡顿
    """
    # 定义信号
    progress_updated = pyqtSignal(int)  # 进度更新信号
    processing_finished = pyqtSignal(bool, str)  # 处理完成信号（成功/失败，消息）
    file_processed = pyqtSignal(str)  # 单个文件处理完成信号

    def __init__(self, video_processor, input_files, output_dir, silence_threshold, min_silence_duration):
        super().__init__()
        self.video_processor = video_processor
        self.input_files = input_files
        self.output_dir = output_dir
        self.silence_threshold = silence_threshold
        self.min_silence_duration = min_silence_duration

    def run(self):
        """执行视频处理"""
        try:
            total_files = len(self.input_files)
            
            for i, input_file in enumerate(self.input_files):
                filename = os.path.basename(input_file)
                output_file = os.path.join(self.output_dir, f"processed_{filename}")
                
                # 处理单个视频文件
                success = self.video_processor.process_video(
                    input_file, 
                    output_file, 
                    self.silence_threshold, 
                    self.min_silence_duration
                )
                
                if success:
                    self.file_processed.emit(filename)
                else:
                    self.processing_finished.emit(False, f"处理文件 {filename} 失败")
                    return
                
                # 更新总体进度
                progress = int((i + 1) / total_files * 100)
                self.progress_updated.emit(progress)
            
            self.processing_finished.emit(True, "所有文件处理完成")
            
        except Exception as e:
            self.processing_finished.emit(False, f"处理过程中出错: {str(e)}")


class DragDropListWidget(QListWidget):
    """
    支持拖放功能的列表控件
    """
    filesDropped = pyqtSignal(list)
    
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setAcceptDrops(True)
    
    def dragEnterEvent(self, event: QDragEnterEvent):
        if event.mimeData().hasUrls():
            event.acceptProposedAction()
    
    def dragMoveEvent(self, event):
        if event.mimeData().hasUrls():
            event.acceptProposedAction()
    
    def dropEvent(self, event: QDropEvent):
        if event.mimeData().hasUrls():
            urls = event.mimeData().urls()
            file_paths = [url.toLocalFile() for url in urls]
            self.filesDropped.emit(file_paths)


class MainWindow(QMainWindow):
    """主窗口类"""
    
    # 支持的文件类型
    SUPPORTED_VIDEO_FORMATS = ['.mp4', '.avi', '.mov', '.mkv', '.wmv', '.flv', '.webm']
    SUPPORTED_AUDIO_FORMATS = ['.mp3', '.wav', '.aac', '.ogg', '.flac', '.m4a']
    
    # 可用的主题
    THEMES = ["Fusion", "Windows", "WindowsVista"]
    
    def __init__(self):
        super().__init__()
        
        # 窗口设置
        self.setWindowTitle("视频静音段落剪辑工具")
        self.setMinimumSize(900, 650)
        
        # 实例化视频处理器
        self.video_processor = VideoProcessor()
        
        # 文件列表
        self.input_files = []
        
        # 设置中心部件
        self.central_widget = QWidget()
        self.setCentralWidget(self.central_widget)
        
        # 主布局
        self.main_layout = QVBoxLayout(self.central_widget)
        self.main_layout.setSpacing(15)
        self.main_layout.setContentsMargins(20, 20, 20, 20)
        
        # 初始化界面元素
        self.init_ui()
        
        # 加载保存的配置
        self.load_config()
        
        # 应用样式表
        self.setStyleSheet(STYLE_SHEET)
        
    def init_ui(self):
        """初始化用户界面"""
        # 标题标签
        title_label = QLabel("视频静音段落剪辑工具")
        title_font = QFont()
        title_font.setPointSize(16)
        title_font.setBold(True)
        title_label.setFont(title_font)
        title_label.setAlignment(Qt.AlignCenter)
        title_label.setContentsMargins(0, 0, 0, 15)
        self.main_layout.addWidget(title_label)
        
        # 顶部部分 - 文件选择
        self.init_file_selection()
        
        # 中间部分 - 参数设置
        self.init_parameters()
        
        # 下部部分 - 进度和状态
        self.init_progress_section()
        
        # 底部部分 - 按钮区域
        self.init_button_section()
        
        # 底部版权信息
        copyright_label = QLabel("© 2023 视频静音段落剪辑工具 v0.1.2")
        copyright_label.setAlignment(Qt.AlignCenter)
        self.main_layout.addWidget(copyright_label)
    
    def init_file_selection(self):
        """初始化文件选择部分"""
        file_group = QGroupBox("文件选择")
        file_layout = QVBoxLayout()
        file_layout.setSpacing(10)
        
        # 拖放提示标签
        drag_hint = QLabel("将文件拖放到此处，或点击下方按钮添加文件")
        drag_hint.setObjectName("dragHint")
        drag_hint.setAlignment(Qt.AlignCenter)
        file_layout.addWidget(drag_hint)
        
        # 文件列表 - 使用支持拖放的自定义列表控件
        self.file_list = DragDropListWidget()
        self.file_list.setMinimumHeight(150)
        self.file_list.filesDropped.connect(self.handle_dropped_files)
        file_layout.addWidget(self.file_list)
        
        # 文件操作按钮
        btn_layout = QHBoxLayout()
        self.btn_add_files = QPushButton("添加文件")
        self.btn_add_files.setIcon(QIcon.fromTheme("document-open"))
        self.btn_clear_files = QPushButton("清空列表")
        self.btn_clear_files.setIcon(QIcon.fromTheme("edit-clear"))
        
        btn_layout.addWidget(self.btn_add_files)
        btn_layout.addWidget(self.btn_clear_files)
        file_layout.addLayout(btn_layout)
        
        # 关联按钮事件
        self.btn_add_files.clicked.connect(self.add_files)
        self.btn_clear_files.clicked.connect(self.clear_files)
        
        file_group.setLayout(file_layout)
        self.main_layout.addWidget(file_group)
    
    def init_parameters(self):
        """初始化参数设置部分"""
        param_group = QGroupBox("参数设置")
        param_layout = QFormLayout()
        param_layout.setSpacing(10)
        param_layout.setFieldGrowthPolicy(QFormLayout.ExpandingFieldsGrow)
        
        # 静音检测阈值
        self.silence_threshold = QDoubleSpinBox()
        self.silence_threshold.setRange(-90.0, 0.0)
        self.silence_threshold.setValue(-30.0)
        self.silence_threshold.setSuffix(" dB")
        self.silence_threshold.setToolTip("低于此分贝值的音频会被识别为静音")
        param_layout.addRow("静音检测阈值:", self.silence_threshold)
        
        # 最小静音持续时间
        self.min_silence_duration = QDoubleSpinBox()
        self.min_silence_duration.setRange(0.1, 10.0)
        self.min_silence_duration.setValue(0.5)
        self.min_silence_duration.setSuffix(" 秒")
        self.min_silence_duration.setToolTip("只有超过此时长的静音才会被删除")
        param_layout.addRow("最小静音持续时间:", self.min_silence_duration)
        
        # 输出目录
        output_layout = QHBoxLayout()
        self.output_dir = QLineEdit()
        self.output_dir.setReadOnly(True)
        self.output_dir.setPlaceholderText("选择输出目录...")
        self.btn_select_output = QPushButton("选择")
        self.btn_select_output.setIcon(QIcon.fromTheme("folder"))
        self.btn_select_output.clicked.connect(self.select_output_dir)
        
        output_layout.addWidget(self.output_dir)
        output_layout.addWidget(self.btn_select_output)
        param_layout.addRow("输出目录:", output_layout)
        
        # 界面主题选择
        theme_layout = QHBoxLayout()
        self.theme_selector = QComboBox()
        self.theme_selector.addItems(self.THEMES)
        self.theme_selector.setCurrentText("Fusion")
        self.theme_selector.currentTextChanged.connect(self.change_theme)
        theme_layout.addWidget(self.theme_selector)
        
        # 深色模式切换
        self.dark_mode_checkbox = QCheckBox("深色模式")
        self.dark_mode_checkbox.stateChanged.connect(self.toggle_dark_mode)
        theme_layout.addWidget(self.dark_mode_checkbox)
        
        param_layout.addRow("界面主题:", theme_layout)
        
        # 保存设置按钮
        self.btn_save_config = QPushButton("保存设置")
        self.btn_save_config.setIcon(QIcon.fromTheme("document-save"))
        self.btn_save_config.clicked.connect(self.save_config)
        param_layout.addRow("", self.btn_save_config)
        
        param_group.setLayout(param_layout)
        self.main_layout.addWidget(param_group)
    
    def init_progress_section(self):
        """初始化进度和状态部分"""
        progress_group = QGroupBox("处理进度")
        progress_layout = QVBoxLayout()
        progress_layout.setSpacing(10)
        
        # 进度条
        self.progress_bar = QProgressBar()
        self.progress_bar.setRange(0, 100)
        self.progress_bar.setValue(0)
        self.progress_bar.setTextVisible(True)
        self.progress_bar.setFormat("%p% 已完成")
        progress_layout.addWidget(self.progress_bar)
        
        # 状态标签
        self.status_label = QLabel("准备就绪")
        self.status_label.setObjectName("statusLabel")
        self.status_label.setAlignment(Qt.AlignCenter)
        progress_layout.addWidget(self.status_label)
        
        progress_group.setLayout(progress_layout)
        self.main_layout.addWidget(progress_group)
    
    def init_button_section(self):
        """初始化底部按钮区域"""
        button_layout = QHBoxLayout()
        
        # 开始处理按钮
        self.btn_start = QPushButton("开始处理")
        self.btn_start.setIcon(QIcon.fromTheme("media-playback-start"))
        self.btn_start.setMinimumHeight(50)
        self.btn_start.setMinimumWidth(200)
        font = QFont()
        font.setPointSize(12)
        font.setBold(True)
        self.btn_start.setFont(font)
        self.btn_start.clicked.connect(self.start_processing)
        
        # 取消按钮
        self.btn_cancel = QPushButton("取消")
        self.btn_cancel.setIcon(QIcon.fromTheme("process-stop"))
        self.btn_cancel.setMinimumHeight(50)
        self.btn_cancel.setMinimumWidth(120)
        self.btn_cancel.setFont(font)
        self.btn_cancel.setEnabled(False)
        self.btn_cancel.clicked.connect(self.cancel_processing)
        
        button_layout.addStretch()
        button_layout.addWidget(self.btn_start)
        button_layout.addWidget(self.btn_cancel)
        button_layout.addStretch()
        
        self.main_layout.addLayout(button_layout)
    
    def change_theme(self, theme_name):
        """更改应用主题"""
        QApplication.setStyle(QStyleFactory.create(theme_name))
        self.save_config()
    
    def toggle_dark_mode(self, state):
        """切换深色/浅色模式"""
        if state == Qt.Checked:
            # 应用深色模式样式
            dark_palette = self.get_dark_palette()
            QApplication.setPalette(dark_palette)
        else:
            # 恢复默认浅色模式
            QApplication.setPalette(QApplication.style().standardPalette())
        self.save_config()
    
    def get_dark_palette(self):
        """获取深色模式调色板"""
        dark_palette = QPalette()
        
        # 文本颜色
        dark_palette.setColor(QPalette.WindowText, QColor(255, 255, 255))
        dark_palette.setColor(QPalette.Text, QColor(255, 255, 255))
        dark_palette.setColor(QPalette.ButtonText, QColor(255, 255, 255))
        
        # 背景颜色
        dark_palette.setColor(QPalette.Window, QColor(53, 53, 53))
        dark_palette.setColor(QPalette.Base, QColor(35, 35, 35))
        dark_palette.setColor(QPalette.AlternateBase, QColor(66, 66, 66))
        dark_palette.setColor(QPalette.Button, QColor(53, 53, 53))
        
        # 高亮色
        dark_palette.setColor(QPalette.Highlight, QColor(42, 130, 218))
        dark_palette.setColor(QPalette.HighlightedText, QColor(255, 255, 255))
        
        # 禁用状态颜色
        dark_palette.setColor(QPalette.Disabled, QPalette.Text, QColor(127, 127, 127))
        dark_palette.setColor(QPalette.Disabled, QPalette.ButtonText, QColor(127, 127, 127))
        
        return dark_palette
    
    def save_config(self):
        """保存用户配置到文件"""
        config = {
            'silence_threshold': self.silence_threshold.value(),
            'min_silence_duration': self.min_silence_duration.value(),
            'output_dir': self.output_dir.text(),
            'theme': self.theme_selector.currentText(),
            'dark_mode': self.dark_mode_checkbox.isChecked()
        }
        
        try:
            with open(CONFIG_FILE, 'w', encoding='utf-8') as f:
                json.dump(config, f, indent=4)
            QMessageBox.information(self, "成功", "设置已保存")
        except Exception as e:
            QMessageBox.warning(self, "错误", f"保存设置时出错: {str(e)}")
    
    def load_config(self):
        """从文件加载用户配置"""
        if not os.path.exists(CONFIG_FILE):
            return
        
        try:
            with open(CONFIG_FILE, 'r', encoding='utf-8') as f:
                config = json.load(f)
            
            # 应用配置
            if 'silence_threshold' in config:
                self.silence_threshold.setValue(config['silence_threshold'])
            
            if 'min_silence_duration' in config:
                self.min_silence_duration.setValue(config['min_silence_duration'])
            
            if 'output_dir' in config and os.path.exists(config['output_dir']):
                self.output_dir.setText(config['output_dir'])
                
            if 'theme' in config and config['theme'] in self.THEMES:
                self.theme_selector.setCurrentText(config['theme'])
                QApplication.setStyle(QStyleFactory.create(config['theme']))
            
            if 'dark_mode' in config:
                self.dark_mode_checkbox.setChecked(config['dark_mode'])
                if config['dark_mode']:
                    dark_palette = self.get_dark_palette()
                    QApplication.setPalette(dark_palette)
                
        except Exception as e:
            print(f"加载配置时出错: {str(e)}")
    
    def handle_dropped_files(self, file_paths):
        """处理拖放的文件"""
        added_count = 0
        for file_path in file_paths:
            # 检查是否是支持的文件类型
            _, ext = os.path.splitext(file_path.lower())
            if ext in self.SUPPORTED_VIDEO_FORMATS + self.SUPPORTED_AUDIO_FORMATS:
                if file_path not in self.input_files:
                    self.input_files.append(file_path)
                    self.file_list.addItem(os.path.basename(file_path))
                    added_count += 1
        
        if added_count > 0:
            self.status_label.setText(f"已添加 {added_count} 个文件")
    
    def add_files(self):
        """添加视频和音频文件"""
        video_formats = " ".join(f"*{fmt}" for fmt in self.SUPPORTED_VIDEO_FORMATS)
        audio_formats = " ".join(f"*{fmt}" for fmt in self.SUPPORTED_AUDIO_FORMATS)
        
        files, _ = QFileDialog.getOpenFileNames(
            self,
            "选择媒体文件",
            "",
            f"媒体文件 ({video_formats} {audio_formats});;视频文件 ({video_formats});;音频文件 ({audio_formats});;所有文件 (*.*)"
        )
        
        if files:
            added_count = 0
            for file in files:
                if file not in self.input_files:
                    self.input_files.append(file)
                    self.file_list.addItem(os.path.basename(file))
                    added_count += 1
            
            if added_count > 0:
                self.status_label.setText(f"已添加 {added_count} 个文件")
    
    def clear_files(self):
        """清空文件列表"""
        if not self.input_files:
            return
            
        self.input_files.clear()
        self.file_list.clear()
        self.status_label.setText("文件列表已清空")
    
    def select_output_dir(self):
        """选择输出目录"""
        directory = QFileDialog.getExistingDirectory(
            self,
            "选择输出目录",
            ""
        )
        
        if directory:
            self.output_dir.setText(directory)
            self.status_label.setText(f"已选择输出目录: {directory}")
    
    def start_processing(self):
        """开始处理视频"""
        # 检查是否有选择文件
        if not self.input_files:
            QMessageBox.warning(self, "警告", "请先添加媒体文件")
            return
        
        # 检查是否设置了输出目录
        if not self.output_dir.text():
            QMessageBox.warning(self, "警告", "请选择输出目录")
            return
        
        # 获取参数
        silence_threshold = self.silence_threshold.value()
        min_silence_duration = self.min_silence_duration.value()
        output_directory = self.output_dir.text()
        
        # 禁用按钮，防止重复操作
        self.btn_start.setEnabled(False)
        self.btn_add_files.setEnabled(False)
        self.btn_clear_files.setEnabled(False)
        self.btn_select_output.setEnabled(False)
        self.btn_save_config.setEnabled(False)
        self.btn_cancel.setEnabled(True)
        
        # 创建并启动工作线程
        self.processing_thread = ProcessingThread(
            self.video_processor,
            self.input_files,
            output_directory,
            silence_threshold,
            min_silence_duration
        )
        
        # 连接信号
        self.processing_thread.progress_updated.connect(self.update_progress)
        self.processing_thread.processing_finished.connect(self.processing_finished)
        self.processing_thread.file_processed.connect(self.file_processed)
        
        # 启动线程
        self.processing_thread.start()
        self.status_label.setText("处理中...")
    
    def cancel_processing(self):
        """取消处理"""
        if hasattr(self, 'processing_thread') and self.processing_thread.isRunning():
            # 终止线程
            self.processing_thread.terminate()
            self.processing_thread.wait()
            
            # 更新界面状态
            self.status_label.setText("处理已取消")
            self.enable_controls()
    
    def update_progress(self, value):
        """更新进度条"""
        self.progress_bar.setValue(value)
    
    def file_processed(self, filename):
        """单个文件处理完成的回调"""
        self.status_label.setText(f"已处理: {filename}")
    
    def processing_finished(self, success, message):
        """处理完成的回调"""
        # 重新启用控件
        self.enable_controls()
        
        # 更新状态
        self.status_label.setText(message)
        
        # 显示结果消息
        if success:
            QMessageBox.information(self, "完成", message)
        else:
            QMessageBox.critical(self, "错误", message)
    
    def enable_controls(self):
        """重新启用控件"""
        self.btn_start.setEnabled(True)
        self.btn_add_files.setEnabled(True)
        self.btn_clear_files.setEnabled(True)
        self.btn_select_output.setEnabled(True)
        self.btn_save_config.setEnabled(True)
        self.btn_cancel.setEnabled(False) 